<?php

    // time and memory benchmarking library
    class benchmark {

        // benchmark marker array
        protected static $benchmark_markers = array();
        // benchmark total duration
        protected static $total_duration = 0;

        // prevents new implimentation
        protected function __construct() {}

        // create new benchmark marker
        public static function create_benchmark_marker($marker_name) {
            $current_time = self::get_microtime();
            // get duration since last marker
            $duration = 0;
            if (self::$benchmark_markers) {
                $last_time = end(self::$benchmark_markers);
                $duration = $current_time - $last_time['end_time'];
            }
            // add to total duration
            self::$total_duration += $duration;
            // add benchmark marker to static array
            self::$benchmark_markers[] = array('name' => $marker_name, 'end_time' => $current_time, 'duration' => $duration, 'memory' => memory_get_usage());
        }

        // report benchmarking
        public static function print_report() {
            self::print_report_head();
            // output each marker line
            foreach (self::$benchmark_markers as $marker_values) {
                if ($marker_values['duration']) {
                    self::print_marker($marker_values, $last_marker_name);
                }
                $last_marker_name = $marker_values['name'];
            }
            self::print_report_foot();
        }

        // get high-precision microtime
        protected static function get_microtime() {
            return preg_replace('/^0(.+?) (.+?)$/', '$2$1', microtime());
        }

        protected static function print_report_head() {
            echo '<table style="clear: both; border-style: none; border-spacing: 1px; background-color: #ccc; font-family: Arial, Helvetica, sans-serif; font-size: 12px;">
                <tr>
                <th style="background-color: #ddd;">Benchmark Range</th>
                <th style="background-color: #ddd;">Seconds</th>
                <th style="background-color: #ddd;">% of Total</th>
                <th style="background-color: #ddd;">Memory Usage</th>
                </tr>';
        }

        protected static function print_marker($marker_values, $last_marker_name) {
            echo '<tr>
                <td style="background-color: #eee;">' . $last_marker_name . ' -> ' . $marker_values['name'] . '</td>
                <td style="text-align: right; background-color: #eee;">' . round($marker_values['duration'], 6) . '</td>
                <td style="text-align: right; background-color: #eee;">' . round(($marker_values['duration'] / self::$total_duration) * 100, 2) . '%</td>
                <td style="text-align: right; background-color: #eee;">' . number_format($marker_values['memory']) . '</td>
                </tr>';
        }

        protected static function print_report_foot() {
            echo '<tr>
                <td style="background-color: #eee;">Total/Peak</td>
                <td style="text-align: right; background-color: #eee;">' . round(self::$total_duration, 6) . '</td>
                <td style="text-align: right; background-color: #eee;">100%</td>
                <td style="text-align: right; background-color: #eee;">' . number_format(memory_get_peak_usage()) . '</td>
                </tr>
                </table>';
        }
    }
?>